home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_sys5 / unixkit.tgz / unixkit.tar / unixkit / thread / ksubr.c < prev    next >
C/C++ Source or Header  |  1991-11-26  |  8KB  |  307 lines

  1. #include <stdio.h>    /***/
  2. /* Machine or compiler-dependent portions of kernel - UNIX version */
  3. #include <signal.h>
  4. #include "global.h"
  5. #include "proc.h"
  6.  
  7. #ifndef NO_INTSTK
  8. extern int16 Intstk[];        /* The signal stack */
  9. #endif
  10.  
  11. /* If you don't have one of those machines you'd better look up the
  12.  * contents of jmp_buf in setjmp.h or in your manual. If those don't
  13.  * give you any hints you will have to write a small program to poke
  14.  * around in a jmp_buf in order to find JB_SP
  15.  */
  16.  
  17. #ifndef JB_SP
  18.  
  19. #if defined(i386)
  20. /* Template for some of the contents of the jmp_buf array on a Sun386i */
  21. #define JB_ONSSTACK 0
  22. #define JB_SP 2     /* Stack pointer */
  23. #endif
  24.  
  25. #if defined(sun4) || defined(sparc)
  26. /* Template for some of the contents of the jmp_buf array on a Sun4. */
  27. #define JB_ONSSTACK 0
  28. #define JB_SP 2     /* Stack pointer */
  29. #endif
  30.  
  31. #if defined(sun3) || defined(mc68020) || defined(mc68000)
  32. /* Template for some of the contents of the jmp_buf array on a Sun3. */
  33. #define JB_ONSSTACK 0
  34. #define JB_SP 2     /* Stack pointer */
  35. #endif
  36.  
  37. #endif
  38.  
  39. void
  40. kinit()
  41. {
  42.     int i;
  43.  
  44.     /* Initialize interrupt stack for high-water-mark checking */
  45. #ifndef NO_INTSTK
  46.     for(i=0;i<INTSTK_SIZE;i++)
  47.         Intstk[i] = STACKPAT;
  48. #endif
  49. }
  50.  
  51. /* ps() will show strange values for the stack usage of the main process.
  52.    This is beacuse we do not fill the stack space of the main process
  53.    with STACKPAT.
  54. */
  55.  
  56. /* Print process table info
  57.  * Since things can change while ps is running, the ready proceses are
  58.  * displayed last. This is because an interrupt can make a process ready,
  59.  * but a ready process won't spontaneously become unready. Therefore a
  60.  * process that changes during ps may show up twice, but this is better
  61.  * than not having it showing up at all.
  62.  */
  63. int
  64. ps(argc,argv,p)
  65. int argc;
  66. char **argv;
  67. void *p;
  68. {
  69.     register struct proc *pp;
  70.     int i;
  71.     jmp_buf env;
  72.  
  73. #ifndef NO_INTSTK
  74.     struct sigstack oss;
  75.     sigstack((struct sigstack *)0,&oss);
  76.     tprintf("Int Stack SP        stksize   maxstk\n");
  77.     tprintf("          %-10lx%-10u%-10u\n",
  78.             (int)oss.ss_sp,INTSTK_SIZE,chkintstk());
  79. #endif
  80.  
  81.     tprintf("PID       SP        stksize   maxstk    event     fl  in  out  name\n");
  82.  
  83.     for(pp = Susptab;pp != NULLPROC;pp = pp->next){
  84.         if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d  %s\n",
  85.          ptol(pp),
  86.          ptol(pp->env[JB_SP]),
  87.          pp->stksize,
  88.          stkutil(pp),
  89.          ptol(pp->event),
  90.          pp->i_state ? 'I' : ' ',
  91.          (pp->state & WAITING) ? 'W' : ' ',
  92.          (pp->state & SUSPEND) ? 'S' : ' ',
  93.          pp->input, pp->output,
  94.          pp->name) == EOF)
  95.             return 0;
  96.     }
  97.     for(i=0;i<PHASH;i++){
  98.         for(pp = Waittab[i];pp != NULLPROC;pp = pp->next){
  99.             if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d  %s\n",
  100.              ptol(pp),ptol(pp->env[JB_SP]),pp->stksize,stkutil(pp),
  101.              ptol(pp->event),
  102.              pp->i_state ? 'I' : ' ',
  103.              (pp->state & WAITING) ? 'W' : ' ',
  104.              (pp->state & SUSPEND) ? 'S' : ' ',
  105.              pp->input,pp->output,
  106.              pp->name) == EOF)
  107.                 return 0;
  108.         }
  109.     }
  110.     for(pp = Rdytab;pp != NULLPROC;pp = pp->next){
  111.         if(tprintf("%-10lx%-10lx%-10u%-10u          %c%c%c %3d %3d  %s\n",
  112.          ptol(pp),ptol(pp->env[JB_SP]),pp->stksize,stkutil(pp),
  113.          pp->i_state ? 'I' : ' ',
  114.          (pp->state & WAITING) ? 'W' : ' ',
  115.          (pp->state & SUSPEND) ? 'S' : ' ',
  116.          pp->input,pp->output,
  117.          pp->name) == EOF)
  118.             return 0;
  119.     }
  120.     setjmp(env);
  121.     if(Curproc != NULLPROC){
  122.         tprintf("%-10lx%-10lx%-10u%-10u          %c   %3d %3d  %s\n",
  123.          ptol(Curproc),ptol(env[JB_SP]),Curproc->stksize,
  124.          stkutil(Curproc),
  125.          Curproc->i_state ? 'I' : ' ',
  126.          Curproc->input,Curproc->output,
  127.          Curproc->name);
  128.     }
  129.     return 0;
  130. }
  131. int
  132. stkutil(pp)
  133. struct proc *pp;
  134. {
  135.     unsigned i;
  136.     register int16 *sp;
  137.  
  138.     if (pp->stack == NULL)return 0;
  139.  
  140.     i = pp->stksize;
  141.     for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
  142.         i--;
  143.     return i;
  144. }
  145. /* Return number of used words in interrupt stack. Note hardwired value
  146.  * for stack size;
  147.  */
  148. chkintstk()
  149. {
  150.     register int i;
  151.     register int16 *cp;
  152.  
  153. #ifndef NO_INTSTK
  154.     for(i=INTSTK_SIZE,cp = Intstk; i != 0 && *cp == STACKPAT; cp++)i--;
  155.     return i;
  156. #else
  157.     return 0;
  158. #endif
  159. }
  160.  
  161. /* Verify that stack pointer for current process is within legal limits;
  162.  * also check that no one has dereferenced a null pointer
  163.  */
  164. void
  165. chkstk()
  166. {
  167.     int16 *sbase;
  168.     int16 *stop;
  169.     int16 *sp;
  170.     jmp_buf env;
  171.  
  172. /* Warning!  KA9WSB
  173.  * Some systems don't reliably tell you that they are on the signal stack.
  174.  * Comment out this routine if that's the case.  It should probably be
  175.  * replaced anyway...
  176.  */
  177.     if(Curproc == NULLPROC)return;
  178.  
  179.     setjmp (env);
  180.     sp = (int16 *) env[JB_SP];
  181. #ifdef JB_ONSSTACK
  182.     if(env[JB_ONSSTACK]){
  183.         /* Probably in interrupt context */
  184.         return;
  185.     }
  186. #endif
  187.     sbase = Curproc->stack;
  188.     if (sbase == 0)
  189.         return;        
  190.     stop = sbase + Curproc->stksize;
  191.     if(sp < sbase || sp >= stop){
  192.         printf("Stack violation, process %s\n",Curproc->name);
  193.         printf("SP = %lx, legal stack range [%lx,%lx)\n",
  194.         ptol(sp),ptol(sbase),ptol(stop));
  195.         fflush(stdout);
  196.         abort();
  197.     }
  198. }
  199. /* Machine-dependent initialization of a task */
  200.  
  201. /* Each process gets a stack below the real stack in the stack area.
  202.    This is really risky business since the kernel thinks that this area
  203.    is unused. Be aware of that this might lead to problems. But it is
  204.    unfortunately the only way to make this program work at the moment,
  205.    since we are not allowed to move the stack pointer below the heap.
  206.  */
  207. void
  208. psetup(pp,iarg,parg1,parg2,pc)
  209. struct proc *pp;    /* Pointer to task structure */
  210. int iarg;        /* Generic integer arg */
  211. void *parg1;        /* Generic pointer arg #1 */
  212. void *parg2;        /* Generic pointer arg #2 */
  213. void (*pc)();        /* Initial execution address */
  214. {
  215.     int i, p;
  216.     void startproc();
  217.  
  218.     /* Task initially runs with interrupts on */
  219.     pp->i_state = 1;
  220.  
  221.     /* The main process needs special treatment. The NULL
  222.        initial execution address indicates that this is indeed
  223.        the main process. */
  224.     if (pc == NULLVFP) {
  225.         pp->stksize = 0;
  226.         pp->stack = NULL;
  227.         return;
  228.     }
  229.  
  230.     /* Since the process has its stack in high memory we are not able
  231.      * write in it directly. So instead of pushing the a stack frame
  232.      * on the stack, we save the frame for later usage by startproc().
  233.      */
  234.  
  235.     pp->startargs.parg2 = parg2;
  236.     pp->startargs.parg1 = parg1;
  237.     pp->startargs.iarg = iarg;
  238.     pp->startargs.func = pc;
  239.  
  240. /***** HACK  we free the stack allocated by kernel.c and get us a new one
  241.  *            that is probably larger and better aligned :-)
  242.  *    When we allocate the stack, we have to leave some room at the
  243.  *    top, because the setjmp function return will presume that it
  244.  *    has a stack frame in which to scribble... so reserve about
  245.  *    256 bytes (64 ints) for the stack...  While we're at it, we
  246.  *    might as well guarantee proper stack alignment.  Align it on
  247.  *    a double-word boundary, which should be the worst case for
  248.  *    most known processors.
  249.  *
  250.  *      What's in the stack frame is important for some processors
  251.  *    (notably the SPARC!).  So, before we do the assignment of
  252.  *    the new stack pointer, we copy the previous stack frame over.
  253.  *    With some assembly we can find the size of the stack frame,
  254.  *    but it's easier just to copy the entire 256 bytes.  NOTE:
  255.  *    IF YOU ADD A LOT OF STUFF TO THIS ROUTINE, THE FRAME MAY
  256.  *    GROW BEYOND THE LIMIT!
  257.  *
  258.  *    Note that this will disturb dbx or anything else that tries
  259.  *    to walk stacks backwards.  It may find a partial stack frame
  260.  *    and crash...
  261.  *
  262.  *******/
  263.     
  264.     free(pp->stack);
  265.     pp->stksize = PROCSTK_SIZE;        /* in small ints */
  266.     pp->stack = (int16 *)malloc(pp->stksize * sizeof(int16));
  267.     for(i=0; i<pp->stksize; i++) pp->stack[i] = STACKPAT;
  268.  
  269.     i = setjmp(pp->env);
  270.     if(i){
  271.         startproc();
  272.     } else {
  273.             /* Compute the new stack top */
  274.         p = (int)pp->stack;
  275.         p = p + (pp->stksize * sizeof(int16));  /* top of stack */
  276.         p = p - 256;        /* fake current stack frame */
  277.         p = (p & 0xfffffff8);    /* fix alignment */
  278.             /* Copy the frame (or most of it, anyway) */
  279.         memcpy((char *)p, (char *)(pp->env[JB_SP]), 256);
  280.             /* And set the new stack pointer. */
  281.         pp->env[JB_SP] = p;
  282.     }
  283. }
  284. /* The process is born and killed here */
  285. void
  286. startproc()
  287. {
  288.     (*Curproc->startargs.func)(Curproc->startargs.iarg,
  289.                    Curproc->startargs.parg1,
  290.                    Curproc->startargs.parg2);
  291.     killself();
  292. }
  293.  
  294. unsigned
  295. phash(event)
  296. void *event;
  297. {
  298.     register unsigned x;
  299.  
  300.     x = (unsigned) event;
  301.  
  302.     /* If PHASH is a power of two, this will simply mask off the
  303.      * higher order bits
  304.      */
  305.     return x % PHASH;
  306. }
  307.